package com.zj.utils.internet;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;

/**
 * OKHttp工具类
 *
 * @author jiang zhu on 2019/4/20
 */
public class NetOkHttpUtils {

    private final static int CONNECT_TIMEOUT = 10;//连接超时时间
    private final static int READ_TIMEOUT = 10;//读取超时时间
    private final static int WRITE_TIMEOUT = 10;//写入超时时间
    private static final String TYPE = "application/octet-stream";
    private static OkHttpClient okHttpClient;
    private static NetOkHttpUtils mNetOkHttpUtils;

    private NetOkHttpUtils() {
        if (okHttpClient == null) {
            okHttpClient = new OkHttpClient.Builder().readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)//设置读取超时时间
                    .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)//设置写的超时时间
                    .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)//设置连接超时时间
                    .build();

        }
    }

    synchronized static NetOkHttpUtils getInstance() {
        if (mNetOkHttpUtils == null) {
            synchronized (NetOkHttpUtils.class) {
                if (mNetOkHttpUtils == null) {
                    mNetOkHttpUtils = new NetOkHttpUtils();
                }
            }

        }
        return mNetOkHttpUtils;
    }

    /**
     * 对请求后获取到的数据进行处理成字符串
     *
     * @param response 返回的请求体
     * @return 返回处理后的字符串
     */
    static String getNetData(okhttp3.Response response) {
        String data = "";
        ResponseBody body = response.body();
        assert body != null;
        InputStream inputStream = body.byteStream();
        StringBuilder stringBuffer = new StringBuilder();
        try {

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String sb;
            while ((sb = bufferedReader.readLine()) != null) {
                stringBuffer.append(sb);
                data = stringBuffer.toString();
            }
            inputStream.close();
            bufferedReader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 进行网络请求没有携带参数的方法
     *
     * @param url      请求路径地址
     * @param callback 设置回调的请求监听方法
     */
    public void postData(String url, Callback callback) {
        RequestBody requestBody = new FormBody.Builder()
                .build();
        Request request = new Request.Builder().url(url)
                .post(requestBody)
                .build();

        Call call = okHttpClient.newCall(request);
        call.enqueue(callback);
    }

    /**
     * 进行网络请求携带一个参数的方法
     *
     * @param url      请求路径地址
     * @param value    携带参数的值的value
     * @param callback 设置回调的请求监听方法
     */
    public void postData(String url, String value, Callback callback) {
        RequestBody requestBody = new FormBody.Builder()
                .add("data", value)
                .build();
        Request request = new Request.Builder().url(url)
                .post(requestBody)
                .build();

        Call call = okHttpClient.newCall(request);
        call.enqueue(callback);


    }

    /**
     * 通过get请求获取数据
     *
     * @param url      url
     * @param callback 返回
     */
    void getData(String url, Callback callback) {
        Request request = new Request.Builder().url(url).build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(callback);
    }

    /**
     * 批量上传文件
     *
     * @param url      地址
     * @param data     数据
     * @param value    值
     * @param files    文件
     * @param callback 返回
     */
    public void postFile(String url, String data, String value, List<File> files, Callback callback) {
        RequestBody requestBody;
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.addFormDataPart(data, value);
        if (files != null) {
            for (int i = 0; i < files.size(); i++) {
                RequestBody fileBody = RequestBody.create(MediaType.parse(TYPE), files.get(i));
                builder.addFormDataPart("files", files.get(i).getName(), fileBody);
            }
        }
        requestBody = builder.build();
        Request request = new Request.Builder().url(url)
                .post(requestBody)
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(callback);

    }

}
